﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


//using HA.ModFlow.Domain.DomainLayer;



namespace HAMath.InverseDistance
{

    /// <summary>
    /// 反距离平方法  插值
    /// </summary>
     public    class InverseDistanceWeighted
     {
        
        /// <summary>
        /// 反距离平方法对点（x，y，z）高程z插值
        /// </summary>
        /// <param name="point3d">观测点的信息(输入参数中的Z值可以不用设置，会返回Z值)</param>
        /// <param name="_centerPoint">采样点（参考点）的信息（其中的Z值可以不用设置，只有二维XY进行计算，哈哈 这是设计的问题。我错了。）</param>
         /// <param name="_planeCenterPointElevation">采样点（参考点）的高程Z值信息  注意 ：顺序要和第二个参数的顺序一致</param>
        /// <returns></returns>
         public static double GetPointElevation(Point3D point3d, List<Point3D> _centerPoint, List<double> _planeCenterPointElevation)
         {
             double n = 2.0;
             if (_centerPoint.Count == 0)
             {
                 return 0.0;
             }
             double D = 0.0;//距离的乘方倒数之和
             double DB = 0.0;
             for (int i = 0; i < _centerPoint.Count; i++)
             {
                 double Distance = GetDistance(point3d, _centerPoint[i]);
                 if (Distance <= 0.0)
                 {
                     D = 0.0;
                     return _planeCenterPointElevation[i];
                     //break;
                 }
                 else
                 {
                     //double Di = 1 / Distance ^ n;
                     double Di = 1 / (Distance * Distance);///
                     D += Di;

                 }
             }

             for (int i = 0; i < _centerPoint.Count; i++)
             {
                 double Distance = GetDistance(point3d, _centerPoint[i]);
                 if (Distance <= 0.0)
                 {
                     D = 0.0;
                     return _planeCenterPointElevation[i];
                 }
                 else
                 {
                     //double Di = 1 / Distance ^ n;
                     double Di = 1 / (Distance * Distance);/////////////////////////////
                     DB += _planeCenterPointElevation[i] * Di / D;
                 }
             }

             return DB;

         }
         /// <summary>
         /// 计算观测点和采样点（参考点）的平面距离 
         /// </summary>
         /// <param name="loc1">观测点</param>
         /// <param name="loc2">采样点（参考点）</param>
         /// <returns></returns>
         private static double GetDistance(Point3D loc1, Point3D loc2)
         {
             double _distance, d1, d2, d3;
             d1 = loc1.X - loc2.X;
             d2 = loc1.Y - loc2.Y;
             //d3 = loc1.Z - loc2.Z;

             _distance = Math.Sqrt(d1 * d1 + d2 * d2);
             //_distance = Math.Sqrt(d1 * d1 + d2 * d2 + d3 * d3);

             return _distance;
         }




    }


}


